import { getToken } from '@U/Auth'
import { storeCommit, storeState } from '@U/common'
import { Msg } from '@C/Msg'
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
import partnerRoutes from '@/router/partner.ts'
import type { IFunc, IObj } from '@/interface'

export interface IRoute {
  // 页面路径
  path: string,
  // 跳转时可选别名
  name: string,
  // 顶端标题
  title?: string,
  // 是否自定义 TitleBar
  titleBar?: boolean,
  titleBarConfig?: IObj,
  // 当前路由哪些身份有权进入
  auth?: Array<string> | boolean,
  // 当前路由不需要登录
  noToken?: boolean,
  // 当前路由是否为 TabBar?
  tab?: boolean,
  // 当前页面存在全局弹窗
  globalTip?: boolean,

  // 分包名，该参数需要与分包目录名相同
  subPack?: string
}

// 打包身份路由
const asyncRoutes = () => partnerRoutes
export const routes = [...(asyncRoutes() as Array<IRoute>)]

// 配置路由跳转方式
const RouterMode = {
  // 保留当前页面，跳转到应用内的某个页面
  navigateTo: 'nav',
  // 跳转到 tabBar 页面，并关闭其他所有非 tabBar 页面
  switchTab: 'tab',
  // 关闭当前页面，跳转到应用内的某个页面。
  redirectTo: 'redirect',
  // 关闭所有页面，打开到应用内的某个页面。
  reLaunch: 'reLaunch',
}
// 路由是否为name
const hasRouteName = (param: string) => Boolean(routes.filter(i => i.name === param).length)
// 路由是否为tabbar
const hasRouteTabBar = (url: string) => Boolean(routes.filter(i => i.path === url)[0].tab)
// 路由是否为subPack
const hasSubPack = (url: string) => routes.filter(i => i.path === url)[0]?.subPack

// 前置拦截
function beforeEach(url: string): boolean {
  let before = true
  const currentRoute = routes.filter((i: IRoute) => i.path === url)[0]
  const auth = currentRoute?.auth ?? 'All'
  const noToken = currentRoute?.noToken ?? false
  if ((asyncRoutes() as Array<IRoute>).map(i => i.path).indexOf(url) !== -1) {
    switch (true) {
        // 未登录
      case !getToken() && !noToken:
        // 身份权限
      case auth !== 'All' && (auth as Array<string>).indexOf(storeState.accountStatus) === -1:
        Msg({ icon: 'error', msg: '当前身份无权限' })
        before = false
    }
  }
  return before
}

// 跳转操作
function navigateTo(urls: string, mode?: string) {
  if (!beforeEach(urls)) return
  storeCommit('routeParams', {})
  const subPack = hasSubPack(urls.split('?')[0])
  const options = { url: `${subPack ? `/${subPack}` : ''}/${urls}` }
  switch (mode) {
    case RouterMode.navigateTo: uni.navigateTo(options); break
    case RouterMode.switchTab: uni.switchTab(options); break
    case RouterMode.redirectTo: uni.redirectTo(options); break
    case RouterMode.reLaunch: uni.reLaunch(options); break
    default: uni.navigateTo(options)
  }
}

// Router
export const Router = {
  // 当前路由
  route() {
    const _route: IObj = getCurrentPages()[getCurrentPages().length - 1]
    let params: IObj = {}
    Object.keys(_route?.options ?? {}).forEach(key => {
      params[key] = _route.options[key]
    })
    params = { ...params, ...storeState.routeParams }
    const subPackList = [...new Set(routes.filter((r: IRoute) => r?.subPack).map((r: IRoute) => r.subPack))]
    const _path = () => {
      const path = _route.route.split('/')
      if (subPackList.indexOf(path[0]) !== -1) return path.slice(1).join('/')
      return path.join('/')
    }
    return {
      path: _path(),
      name: routes.filter((i: IRoute) => i.path === _path())[0].name,
      params,
    }
  },
  // 路由跳转
  push(url_name: string, params?: IObj, mode?: string) {
    // 拦截路由name
    if (hasRouteName(url_name)) return this.check(url_name, params, mode)
    // 跳转TabBar？
    const isTab = hasRouteTabBar(url_name)
    // 配置路由参数
    if (params !== undefined && !isTab) {
      let urls = `${url_name}?`
      const arr = []
      for (const key in params) {
        if (Object.hasOwnProperty.call(params, key)) {
          const element = params[key]
          const str = `${key}=${element}`
          arr.push(str)
        }
      }
      urls += arr.join('&')
      navigateTo(urls, mode)
      storeCommit('routeParams', (params || {}))
    } else {
      navigateTo(url_name, mode === 'reLaunch' ? mode : isTab ? 'tab' : mode)
      storeCommit('routeParams', (params || {}))
    }
  },
  // 名称跳转
  check(name: string, params?: IObj, mode?: string) {
    routes.forEach(item => {
      if (item.name === name) {
        this.push(item.path, params, mode)
      }
    })
  },
  // 重定向
  redirect(url_name: string, params?: IObj) {
    this.push(url_name, params, 'redirect')
  },
  // 重载
  reLaunch(url_name: string, params?: IObj) {
    this.push(url_name, params, 'reLaunch')
  },
  // 路由返回
  back(deep?: number | string, params?: IObj) {
    const pages = getCurrentPages()
    console.log('pages', pages)
    let backDeep = 1
    if (typeof deep === 'string') {
      let pagePath = deep
      routes.forEach(item => {
        if (item.name === deep || item.path === deep) {
          pagePath = item.path
        }
      })
      const backDeepIndex = pages.map((page: IObj) => page.route).indexOf(pagePath)
      backDeep = backDeepIndex !== -1
          ? (pages.length - (backDeepIndex + 1))
          : 1
    }
    if (typeof deep === 'number') {
      backDeep = deep || 1
    }
    if (params) {
      storeCommit('routeParams', params)
    }
    uni.navigateBack({ delta: backDeep })
  },
}
